import { defineStore } from 'pinia'
import { ref, computed, watch, reactive } from 'vue'
import { StorageKey } from '../utils/enum'
import default_config from '../config/default_config'
import * as math from 'mathjs'
import { useGameStore } from './gameStore'
import { useLogStore } from './log'
import dayjs from 'dayjs'
import { useResourcesStore } from './resources'
import { useBuildingsStore } from './building'
import { Pokemon, PokemonAction, PokemonUiView } from '../types/pokemon'

// 宝可梦可能的行为动作列表
const POKEMON_ACTIONS: PokemonAction[] = default_config.action

const { POKEMON_ENCOUNTER_PROBABILITY, MAX_HAPPINESS_EFFECT, HAPPINESS_PEAK } =
  default_config.basic

// 随机获取一个宝可梦行为
const getRandomAction = (): PokemonAction => {
  return POKEMON_ACTIONS[Math.floor(Math.random() * POKEMON_ACTIONS.length)]
}

// 宝可梦停留概率
// 新公式设计满足以下要求：
// 1. probability为100的，不论幸福点数为多少必定出现(概率为1)
// 2. probability为0的，不论幸福点数为多少必定不出现(概率为0)
// 3. probability越接近100，受幸福点数影响越小
// 4. probability越接近0，受幸福点数影响较大，但不要过于极端
// 5. 低于1%的基础概率不受幸福点数影响
// 6. 幸福点数在0-75之间时差距逐渐增大，在75-100之间差距回落
//
// 新公式:
// 如果 probability <= 0:
//   0 (必定不出现)
// 如果 probability >= 100:
//   1 (必定出现)
// 如果 0 < probability < 1:
//   probability / 100 (不受幸福点数影响)
// 否则:
//   baseProb + ((100 - probability) / 100)^1.5 * happinessEffect * MAX_HAPPINESS_EFFECT
//   其中 happinessEffect 是一个基于幸福点数的曲线函数，在75点时达到峰值
const getStayProbability = (probability: number, happyPoint: number) => {
  // 如果概率为0，则必定不出现
  if (probability <= 0) {
    return 0
  }

  // 如果概率为100，则必定出现
  if (probability >= 100) {
    return 1
  }

  // 将1-100范围转换为0-1的基础概率
  const baseProb = probability / 100

  // 如果基础概率小于1%，则不受幸福点数影响
  if (probability < 1) {
    return baseProb
  }

  // 计算幸福点数效果曲线
  // 使用二次函数模拟在75点时达到峰值，之后回落的曲线
  let happinessEffect = 0
  if (happyPoint <= HAPPINESS_PEAK) {
    // 0-75区间，使用加速增长的曲线
    happinessEffect = Math.pow(happyPoint / HAPPINESS_PEAK, 2)
  } else {
    // 75-100区间，使用缓慢增长接近1的曲线
    const remaining = (happyPoint - HAPPINESS_PEAK) / (100 - HAPPINESS_PEAK)
    happinessEffect = 1 - Math.pow(1 - remaining, 2) * 0.2
  }

  // 计算幸福点数带来的增益
  // 使用更复杂的S形曲线函数计算概率因子
  // 这个公式结合了对数和sigmoid函数的特性，在低概率时增长更快，高概率时增长更慢
  // 同时在中间区域有一个平滑的过渡
  const normalizedProb = probability / 100
  const sigmoid = 1 / (1 + Math.exp(5 * (normalizedProb - 0.5)))
  const logComponent = -Math.log10(normalizedProb + 0.1) / 10 + 0.5
  const probabilityFactor = sigmoid * logComponent * 1.2
  const happinessBonus = Math.min(
    probabilityFactor * happinessEffect * MAX_HAPPINESS_EFFECT,
    MAX_HAPPINESS_EFFECT
  )

  // 最终概率 = 基础概率 + 幸福点数增益
  return Math.min(baseProb + happinessBonus, 1)
}

// 捕捉概率计算
// 影响参数 家园基础捕获力、宝可梦捕捉难度、行为动作影响系数
const calculateCatchProbability = (
  pokemonId: string,
  actionEffect: number,
  baseCatchPower: number = 10
) => {
  // 获取宝可梦数据
  const pokemon = window.$poketmon.getDataById(pokemonId)
  if (!pokemon) return 0

  // 新算法：宝可梦捕获难度占据60%的影响力，家园基础占据30%, 行为动作占据10%

  // 1. 宝可梦基础捕获难度（0-100，值越大越难捕获）
  // 将其转换为捕获概率（0-1，值越大越容易捕获）
  let pokemonCatchFactor = Math.max(0, 1 - pokemon.catchDifficulty / 100) * 0.6

  // 对低难度宝可梦增加额外捕获概率
  if (pokemon.catchDifficulty < 10) {
    // 低于10的增加20个百分点
    pokemonCatchFactor += 0.2
  } else if (pokemon.catchDifficulty < 30) {
    // 低于30但高于10的增加10个百分点
    pokemonCatchFactor += 0.1
  } else if (pokemon.catchDifficulty < 50) {
    // 低于50高于30的增加5个百分点
    pokemonCatchFactor += 0.05
  }

  // 2. 家园基础捕获力（通常为正数，值越大越容易捕获）
  // 标准化为0-1范围（假设最大值为50）
  const homeCatchFactor = Math.min(baseCatchPower / 50, 1) * 0.3

  // 3. 行为动作影响（范围为-15到30，正数增加概率，负数降低概率）
  // 标准化为-0.1到0.1范围
  const actionFactor = Math.max(-0.1, Math.min(actionEffect / 30, 0.1))

  // 计算最终捕获概率（三个因素的加权和）
  const catchProbability = pokemonCatchFactor + homeCatchFactor + actionFactor

  // 限制概率在0-1之间
  return Math.max(0, Math.min(1, catchProbability))
}

// 处理宝可梦name
const getPokemonName = (name: string, uiView: PokemonUiView) => {
  const _color = uiView.themeColor
  return `<span style="color: ${_color}">${name}</span>`
}

export const usePokemonStore = defineStore('pokemon', () => {
  const data = ref({})

  const state = reactive({
    isRunning: true,
  })

  const logStore = useLogStore()
  const resourcesStore = useResourcesStore()

  // 检查是否有出现的宝可梦
  const update = async () => {
    if (!useGameStore().gameState.isRunning) {
      return
    }
    if (!state.isRunning) {
      return
    }
    console.log('搜寻宝可梦中....')

    let _item = null
    let _logId = null
    let pokemonWithAction = null

    // 使用可选链和类型断言来获取幸福点数
    const happyPoint =
      (resourcesStore.data as any).happinessPoints?.details.value || 0

    if (math.random(0, 1) < POKEMON_ENCOUNTER_PROBABILITY) {
      const poketmonData = window.$poketmon.dataArr
      // 随机选择一个宝可梦
      _item = poketmonData[Math.floor(Math.random() * poketmonData.length)]

      if (happyPoint < _item.requiredHappyPoint) {
        return
      }

      const stayProbability = getStayProbability(_item.probability, happyPoint)
      const _stay = math.random(0, 1)

      if (_stay > stayProbability) {
        return
      }

      // 随机赋予一个行为动作
      const action = getRandomAction()
      pokemonWithAction = {
        ..._item,
        currentAction: action,
      }

      const content1 = `出现了野生的${getPokemonName(_item.name, _item.uiView)}！${action.description}`
      const content2 = ` <br><span style="opacity:0.75">它似乎失去了兴趣，准备离开了</span>`
      const content3 = `${getPokemonName(_item.name, _item.uiView)} 逃走了`

      // 记录遇到宝可梦的日志
      _logId = logStore.addLog({
        type: 'pokémon',
        source: 'pokémon',
        content: content1,
        isTop: true,
        pokemonConfig: {
          id: _item.id,
          action: action,
          icon: _item.icon,
        },
      })
      stopUpdate()

      await new Promise((resolve) => setTimeout(resolve, 1000000))
      if (!state.isRunning) {
        logStore.updateLog(_logId, {
          content: content1 + content2,
        })
      } else {
        return
      }
      await new Promise((resolve) => setTimeout(resolve, 1000000))
      if (!state.isRunning) {
        logStore.updateLog(_logId, {
          type: 'error',
          content: content3,
          isTop: false,
        })
      } else {
        return
      }
    }
  }

  // 更新行为动作
  const updateAction = (
    logId: string,
    pokemonId: string,
    action?: PokemonAction
  ) => {
    const _action = action || getRandomAction()
    const pokemon = window.$poketmon.getDataById(pokemonId)
    const log = logStore.getLog(logId)

    logStore.updateLog(logId, {
      content: `捕捉${getPokemonName(pokemon?.name, pokemon?.uiView)}失败了！${_action.description}`,
      pokemonConfig: {
        id: log?.pokemonConfig?.id,
        action: {
          ...log?.pokemonConfig?.action,
          description: _action.description,
          catchDifficultyEffect: _action?.catchDifficultyEffect,
        },
        icon: log?.pokemonConfig?.icon,
      },
    })
  }

  // 暂停检查
  const stopUpdate = () => (state.isRunning = false)

  // 恢复检查
  const resumeUpdate = () => (state.isRunning = true)

  return {
    data,
    update,
    calculateCatchProbability,
    updateAction,
    resumeUpdate,
    getPokemonName,
  }
})
